#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/kdev_t.h>

#define BUFFER_SIZE 1024 //设备可保存信息的字节数
#define MAJOR_ID 222     //设备号

char buf[BUFFER_SIZE] = "It's czy's drive."; //设备保存的信息

static int my_open(struct inode *inode, struct file *file);
static int my_release(struct inode *inode, struct file *file);
static ssize_t my_read(struct file *file, char __user *user, size_t count, loff_t *f_pos);
static ssize_t my_write(struct file *file, const char __user *user, size_t count, loff_t *f_pos);

struct file_operations czy_fops =
    {
        .owner = THIS_MODULE,
        .open = my_open,
        .release = my_release,
        .read = my_read,
        .write = my_write,
};

static int my_open(struct inode *inode, struct file *file)
{
    printk("Open my device OK!\n");
    try_module_get(THIS_MODULE);
    return 0;
}

static int my_release(struct inode *inode, struct file *file)
{
    printk("My device release!\n");
    module_put(THIS_MODULE);
    return 0;
}

//读取数据
static ssize_t my_read(struct file *file, char __user *user, size_t count, loff_t *f_pos)
{
    if (copy_to_user(user, buf, sizeof(buf)))
        return -2;
    return sizeof(buf);
}

//写入数据
static ssize_t my_write(struct file *file, const char __user *user, size_t count, loff_t *f_pos)
{
    if (copy_from_user(buf, user, sizeof(buf)))
        return -3;
    return sizeof(buf);
}

int my_init(void)
{
    int ret = register_chrdev(MAJOR_ID, "czy_device", &czy_fops);
    if (ret < 0)
    {
        printk("Register_chrdev error!\n");
        return -1;
    }
    printk("LgsDrive has been registered!\n");
    printk("ID: %d\n", ret);
    return 0;
}

void my_exit(void)
{
    unregister_chrdev(MAJOR_ID, "czy_device");
    printk("Unregister OK!\n");
}

module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("czy"); //作者
MODULE_LICENSE("GPL");